package ginhttp

import (
	"context"
	"errors"
	"fmt"
	"net/http"
	"strings"
	"time"

	"gitee.com/night-tc/gobige/global"
	"gitee.com/night-tc/gobige/logger"
	"gitee.com/night-tc/gobige/sess"
	"gitee.com/night-tc/gobige/threads"
	"github.com/gin-gonic/gin"
)

/*
使用gin库做为路由的http服务
*/
type HttpMgr struct {
	engine  *gin.Engine
	httpSrv *http.Server
	thgo    *threads.ThreadGo
	cfg     *global.ListenCfg
}

func NewHttpMgr(thgo *threads.ThreadGo, cfg *global.ListenCfg, eng *gin.Engine) (result *HttpMgr) {
	result = new(HttpMgr)
	result.thgo = threads.NewThreadGoByGo(thgo)
	result.cfg = cfg
	if global.GetCfgInst().GetRecover() {
		gin.SetMode(gin.ReleaseMode)
	}
	result.engine = eng

	result.httpSrv = &http.Server{
		Addr:              cfg.Listen,
		Handler:           result.engine,
		ReadTimeout:       time.Second * 30,
		ReadHeaderTimeout: time.Second * 30,
		WriteTimeout:      time.Second * 30,
		IdleTimeout:       time.Second * 30,
		MaxHeaderBytes:    1 << 20,
	}
	return
}

// // 获取路由器设置http的路由信息
// func (this HttpMgr) GetRouter() gin.IRouter {
// 	return this.Engine
// }

func (this *HttpMgr) Start() error {
	li, port := sess.GetListener("tcp", this.cfg) // net.Listen("tcp", this.cfg.Listen)
	this.engine.GET("pinginfo", this.pinginfo)
	this.thgo.Go(func(ctx context.Context) {
		err := this.httpSrv.Serve(li)
		if err != nil {
			if !strings.Contains(err.Error(), "use of closed network connection") && !errors.Is(err, http.ErrServerClosed) {
				panic(err)
			}
		}
	})
	this.thgo.Go(func(ctx context.Context) {
		<-ctx.Done()
		this.httpSrv.Shutdown(ctx)
	})
	this.cfg.Addr = fmt.Sprint(this.cfg.Addr, ":", port)
	logger.Infof("http start.addr:%s", this.cfg.Addr)
	return nil
}

func (this *HttpMgr) Stop() {
	this.thgo.CloseWait()
}

func (this *HttpMgr) pinginfo(ctx *gin.Context) {
	ctx.JSONP(http.StatusOK, gin.H{
		"ServiceInfo": gin.H{
			"ServerID": global.GetCfgInst().GetServerID(),
			"GroupID":  global.GetCfgInst().GetGroupID(),
			"SrvType":  global.GetCfgInst().GetSrvType(),
		},
	})
}
